/*
 * SmallMemoryFootprintTreebank.java
 *
 * Created on February 28, 2007, 12:33 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package galronnlp.perceptron;

import galronnlp.io.PennTreeReader;
//import galronnlp.perceptron.PennTreeBankIterator;
import galronnlp.util.ProductionGenerator;
import galronnlp.util.Symbol;
import galronnlp.util.SymbolGenerator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;

/**
 *
 * @author Dennis N. Mehay
 */
public class SmallMemoryFootprintTreebank extends LinkedList<Node> {
    
    public static final int FULL     = 0;
    public static final int SAMPLE   = 1;
    public static final int WSJ      = 2;
    public static final int BROWN    = 3;
    public static final int WSJ_ONE_FILE = 4;   

    private int treeCount = 0;
    private PennTreeReader reader = null;
    private BufferedReader buff = null;
    private FileReader fr = null;
    private Grammar g = null;
    private String trainingFile = "";
    
    protected int corpus = WSJ;
    protected String CorpusRoot = "";
    protected SymbolGenerator sg;
    protected int from, to;
    
    ///** Creates a new instance of SmallMemoryFootprintTreebank */
    //public SmallMemoryFootprintTreebank(String root, int sample, int corpus, SymbolGenerator sg, int fromFile, int toFile) {
    //    super(root, sample, corpus, sg, fromFile, toFile);                
    //    g = new Grammar(new ProductionGenerator(), sg);
    //}
    
    /** Creates a new instance of SmallMemoryFootprintTreebank */
    public SmallMemoryFootprintTreebank(int sample, SymbolGenerator sg, String trainingFile) {
        //super("blahblahblah", sample, WSJ, sg);
        this.corpus = WSJ_ONE_FILE;
        g = new Grammar(new ProductionGenerator(), sg);
        this.trainingFile = trainingFile;
    }
    
    
    ///** Creates a new instance of SmallMemoryFootprintTreebank */
    //public SmallMemoryFootprintTreebank(String root, int sample, int corpus, SymbolGenerator sg) {
    //    super(root, sample, corpus, sg);
    //    g = new Grammar(new ProductionGenerator(), sg);     
    //}
    
    ///** Creates a new instance of SmallMemoryFootprintTreebank */
    //public SmallMemoryFootprintTreebank(String root, SymbolGenerator sg) {
    //    this(root, FULL, WSJ, sg);
    //}

    public void build() {
        if(this.corpus == WSJ_ONE_FILE)
            this.readInTrainingFile(this.trainingFile);
        else if(corpus == BROWN)
            System.err.println("NOT YET IMPLEMENTED");
        else
            System.err.println("NOT YET IMPLEMENTED");
    }
    
    public int size() {
        return this.treeCount;
    }

    public boolean containsAll(Collection<?> c) {
        return true;
    }
    
    public Node next() {
        return reader.readNodeTree();
    }
    
    public PennTreebankIterator iterator() {
        return new PennTreebankIterator(this.trainingFile, new SymbolGenerator(), this.size());
    }
    
    private void readInTrainingFile(String f) {   
        String file = this.CorpusRoot + f;
        int count = 0;
        try { 
            if(this.fr!=null) { this.fr.close(); this.fr=new FileReader(file); }
            else { this.fr = new FileReader(file); }
                    
            if(this.buff!=null) { this.buff.close(); this.buff=new BufferedReader(this.fr); }
            else { this.buff = new BufferedReader(this.fr); }
           
            while(buff.readLine()!=null) {count++;}
            this.treeCount = count;
            buff.close();
            //this.fr=new FileReader(file);
            //this.buff = new BufferedReader(this.fr);
            //this.reader = new PennTreeReader(this.buff, this.sg);            
        } catch(Exception e) {
            e.printStackTrace();
        }
                
    }
    //private void readInWSJ() {
    //    if(sample == FULL) this.readInWSJFull();
    //    else if(sample == SAMPLE) this.readInWSJSample();
    //    //this.readInFirstTrees();
    //}
    
    //private void readInWSJFull() {
    //    this.readInWSJFromTo(2,21);
    //}
    
    //private void readInWSJFromTo(int from, int to) {
    //    int fileNum = 1;
    //    int dirNum  = 0;
    //    String fileExt = ".mrg.transformed";
    //    CorpusRoot += "/mrg/wsj/";
    //    for(dirNum = from; dirNum < (to+1); dirNum++) {
    //        String dirString = "";
    //        if(dirNum < 10) dirString = "0" + Integer.toString(dirNum);
    //        else dirString = Integer.toString(dirNum);
    //        String fileString = "";
    //        if(dirNum == 0) {
    //            for(fileNum = 1; fileNum < 100; fileNum++) {
    //                fileString = "";
    //                if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
    //                else fileString = Integer.toString(fileNum);
    //                System.err.println(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //                treeCount += this.countTrees(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //            }
    //        }
    //        else if(dirNum == 3) {
    //            for(fileNum = 0; fileNum < 81; fileNum++) {
    //                fileString = "";
    //                if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
    //                else fileString = Integer.toString(fileNum);
    //                System.err.println(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //                treeCount += this.countTrees(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //            }
    //            
    //        }
    //        else if(dirNum == 8) {
    //            for(fileNum = 0; fileNum < 21; fileNum++) {
    //                fileString = "";
    //                if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
    //                else fileString = Integer.toString(fileNum);
    //                System.err.println(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //                treeCount += this.countTrees(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //            }
    //            
    //        }
    //        else if(dirNum == 21) {
    //            for(fileNum = 0; fileNum < 73; fileNum++) {
    //                fileString = "";
    //                if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
    //                else fileString = Integer.toString(fileNum);
    //                System.err.println(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //                treeCount += this.countTrees(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //            }
    //       }
    //        else if(dirNum == 21) {
    //            for(fileNum = 0; fileNum < 73; fileNum++) {
    //                fileString = "";
    //                if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
    //                else fileString = Integer.toString(fileNum);
    //                System.err.println(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //                treeCount += this.countTrees(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //            }
    //        }
    //        else if(dirNum == 22) {
    //            for(fileNum = 0; fileNum < 83; fileNum++) {
    //                fileString = "";
    //                if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
    //                else fileString = Integer.toString(fileNum);
    //                System.err.println(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //                treeCount += this.countTrees(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //            }
    //        }
    //        else {
    //            for(fileNum = 0; fileNum < 100; fileNum++) {
    //                fileString = "";
    //                if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
    //                else fileString = Integer.toString(fileNum);
    //                System.err.println(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //                treeCount += this.countTrees(CorpusRoot + dirString + "/wsj_" + dirString + fileString + fileExt);
    //            }
    //        }
    //    }
    //}
    
    /** Assumes one parse per line. */
    private int countTrees(String file) {
        int count = 0;
        try { 
            if(this.fr!=null) { this.fr.close(); this.fr=new FileReader(file); }
            else { this.fr = new FileReader(file); }
                    
            if(this.buff!=null) { this.buff.close(); this.buff=new BufferedReader(this.fr); }
            else { this.buff = new BufferedReader(this.fr); }
           
            while(buff.readLine()!=null) {count++;}
            buff.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
        return count;
    }
    
    //private void readInWSJSample() {
    //    CorpusRoot += "parsed/mrg/wsj/";
    //    for(int fileNum = 1; fileNum < 100; fileNum++) {
    //        String fileString = "";
    //        if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
    //        else fileString = Integer.toString(fileNum);
////            System.err.println("wsj_00" + fileString + ".mrg");
    //        this.readInWSJTreeFile(CorpusRoot + "00" + "/wsj_" + "00" + fileString + ".mrg");
    //   }
    //}
    
    private int readInWSJTreeFile(String file) {
        int count = 0;        
        try { 
            if(this.fr!=null) { this.fr.close(); this.fr=new FileReader(file); }
            else { this.fr = new FileReader(file); }
                    
            if(this.buff!=null) { this.buff.close(); this.buff=new BufferedReader(this.fr); }
            else { this.buff = new BufferedReader(this.fr); }
           
            if(this.reader!=null) { this.reader.close(); this.reader = new PennTreeReader(buff); }
            else { this.reader = new PennTreeReader(buff, this.sg); } 
            Node tree = null;
            while(reader.hasNext()) {
                tree = reader.readNodeTree();
                if(tree != null) { this.addLast(tree); }
            }
            reader.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
        return count;
    }

    public String toString() {
        String ret = "---------------------------------------\n";
        for(PennTreebankIterator i = this.iterator(); i.hasNext(); ) {
            ret += i.next();
            ret += "---------------------------------------\n";
        }
        return ret;
    }
    
    public static void main(String[] args) {
        SymbolGenerator sg = new SymbolGenerator();
        SmallMemoryFootprintTreebank bank = new SmallMemoryFootprintTreebank(Integer.parseInt(args[0]), sg, args[1]);
        bank.build();
        System.out.println("Done! Treebank size = " + bank.size());
        PennTreebankIterator it = bank.iterator();
        Grammar g = new Grammar(new ProductionGenerator(), sg);
        Node n = null;
        while(it.hasNext()) {
            n = it.next();
            n.addToGrammar(g);
            System.err.println("added parse # "+it.indexOf()+" to the grammar.");
        }
        g.writeXML(new File(args[2]));
        //System.out.println("---------------------------------------\n");
    }
}

